home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK1.toast / Development Kits (Disc 1) / AppleScript / Development Tools / Sample Code / Sample OSA Component / In MW C with Tester / ComponentTester.c next >
Encoding:
Text File  |  1995-11-08  |  34.9 KB  |  1,524 lines  |  [TEXT/MMCC]

  1. /************************************************************************************
  2.  
  3.     File:        ComponentTester.c
  4.  
  5.     Contains:    Component tester routines.
  6.  
  7.     Written by:    Gary Woodcock
  8.  
  9.     Copyright:    © 1992 by Apple Computer, Inc.
  10.  
  11.     Change History (most recent first):
  12.     
  13.     Simplified it for the OSASampleComponent code 
  14.     
  15.     Ramon Silva  11/8/95  
  16.     
  17. ************************************************************************************/
  18.  
  19.  
  20. //-----------------------------------------------------------------------
  21. // 
  22.  
  23. #define  DEBUG_IT //comment this out when not debugging 
  24.  
  25. #include "MyOSAComponent.h"
  26. #include "MyOSAComponentRoutines.h"
  27.  
  28. #include <Menus.h>
  29. #include <Windows.h>
  30. #include <QuickDraw.h>
  31. #include <OSEvents.h>
  32. #include <Resources.h>
  33. #include <Desk.h>
  34. #include <Fonts.h>
  35. #include <ToolUtils.h>
  36.  
  37. #ifndef THINK_C
  38.     #include <Packages.h>
  39. #endif THINK_C
  40.  
  41. #define kGenericError -1
  42.  
  43.  
  44. //-----------------------------------------------------------------------
  45. // Constants
  46.  
  47. // Maximum number of instances our app can open
  48. #define    kMaxInstances    10
  49.  
  50. // Menu bar
  51. enum
  52. {
  53.     kMenuBarID = 128
  54. };
  55.  
  56. // Menus
  57. enum
  58. {
  59.     kAppleID = 128,
  60.     kFileID,
  61.     kEditID,
  62.     kTestID,
  63.     kCanDoID,
  64.     kInstanceID
  65. };
  66.  
  67. // Apple menu items
  68. enum
  69. {
  70.     kAboutItem = 1
  71. };
  72.  
  73. // File menu items
  74. enum
  75. {
  76.     kOpenItem = 1,
  77.     kCloseItem,
  78.     kOpenComponentItem = 4,
  79.     kCloseComponentItem,
  80.     kQuitItem = 7
  81. };
  82.  
  83. // Edit menu items
  84. enum
  85. {
  86.     kUndoItem = 1,
  87.     kCutItem = 3,
  88.     kCopyItem,
  89.     kPasteItem,
  90.     kClearItem
  91. };
  92.  
  93. // Test menu items
  94. enum
  95. {
  96.     kGetNameItem = 1,
  97.     kGetInfoItem,
  98.     kGetVersionItem,
  99.     kGetCountItem,
  100.     kGetRefconItem,
  101.     kCanDoItem = 7,
  102.     kDoIt = 9
  103. };
  104.  
  105. // Can Do hierarchical menu items
  106. enum
  107. {
  108.     kCanDoOpenItem = 1,
  109.     kCanDoCloseItem,
  110.     kCanDoCanDoItem,
  111.     kCanDoVersionItem,
  112.     kCanDoRegisterItem,
  113.     kCanDoTargetItem
  114. };
  115.  
  116. // Registration flags
  117. enum
  118. {
  119.     kRegisterLocally = 0,
  120.     kRegisterGlobally
  121. };
  122.  
  123. // Dialog IDs
  124. enum
  125. {
  126.     kAboutDialogID = 128,
  127.     kStatusDialogID,
  128.     kOpDialogID
  129. };
  130.  
  131. // Common DITL items
  132. enum
  133. {
  134.     kOKButton = 1,
  135.     kCancelButton,
  136.     kOKButtonOutline
  137. };
  138.  
  139. // DITL items for operations dialog
  140. enum
  141. {
  142.     kFirstNumBox = 3
  143. };
  144.  
  145. // DITL items for status dialog
  146. enum
  147. {
  148.     kStatusBox = 1
  149. };
  150.  
  151. // String list
  152. enum
  153. {
  154.     kStatusStrsID = 128
  155. };
  156.  
  157. // Strings
  158. enum
  159. {
  160.     kIdleStr = 1,
  161.     kFoundCompIDAndInstStr,
  162.     kDidNotFindCompIDStr,
  163.     kDidNotGetInstStr,
  164.     kClosedOKStr,
  165.     kErrorClosingInstStr,
  166.     kCompVersStr,
  167.     kInterfaceVersStr,
  168.     kCanDoOpenStr,
  169.     kCantDoOpenStr,
  170.     kCanDoCloseStr,
  171.     kCantDoCloseStr,
  172.     kCanDoCanDoStr,
  173.     kCantDoCanDoStr,
  174.     kCanDoVersionStr,
  175.     kCantDoVersionStr,
  176.     kCanDoRegisterStr,
  177.     kCantDoRegisterStr,
  178.     kCanDoTargetStr,
  179.     kCantDoTargetStr,
  180.     kNameStr,
  181.     kNoNameStr,
  182.     kInfoStr,
  183.     kNoInfoStr,
  184.     kRefconStr,
  185.     kThereIsStr,
  186.     kThereAreStr,
  187.     kInstanceStr,
  188.     kInstancesStr,
  189.     kCantOpenAnyMoreInstStr,
  190.     kCompDescStr,
  191.     kOSAStr,
  192.     kKeyPhrase
  193. };
  194.  
  195.  
  196. //-----------------------------------------------------------------------
  197. // Globals
  198.  
  199. MenuHandle            gAppleMenu;
  200. MenuHandle            gFileMenu;
  201. MenuHandle            gEditMenu;
  202. MenuHandle            gTestMenu;
  203. MenuHandle            gCanDoMenu;
  204. MenuHandle            gInstanceMenu;
  205. EventRecord            gTheEvent;
  206. Component            gOSAComponentID;
  207. ComponentInstance    gComponentInstance [kMaxInstances];
  208. ComponentInstance    gCurrentInstance;
  209. DialogPtr            gStatusDialog;
  210. GrafPtr                gSavedPort;
  211. Str255                gStatusStr;
  212. Rect                gStatusBox;
  213. Handle                gStatusText;
  214. Handle                gOSANameHdl;
  215. Handle                gInfoHdl;
  216. Str255                gKeyPhrase;
  217. Boolean                gQuitFlag;
  218.  
  219. //-----------------------------------------------------------------------
  220. // Prototypes
  221.  
  222. void                DoInit                    (void);
  223. void                DoMenuSetup                (void);
  224. void                HandleEvent                (void);
  225. void                HandleMouseDown            (void);
  226. void                AdjustMenus                (void);
  227. void                Enable                    (Handle        menu,
  228.                                              short        item,
  229.                                              Boolean    ok);
  230. void                HandleMenu                (long        menu);
  231. void                OpenStatus                (void);
  232. void                UpdateStatus            (void);
  233. void                DoAboutDialog            (void);
  234. void                OpenOSAComponent        (void);
  235. void                DoOperationDialog        (Str63 theNumber);
  236. static pascal void    DrawOKOutline            (DialogPtr    theDialog,
  237.                                              short        theItem);
  238. void                DoQuit                    (void);
  239. void                DecimalNumberToHexStr    (long        theDecimalNumber,
  240.                                              StringPtr    theHexStr);
  241. OSErr                HexStrToDecimalNumber    (StringPtr    theHexStr,
  242.                                              long        *theDecimalNumber);
  243. extern pascal         ComponentResult OSADispatcher    (ComponentParameters *params, char **storage);
  244. OSErr                  MyDoNewScript            (Str63 theNumber, Str63 theResult);
  245. void                 MyGetScriptErrorInfo    (short *theErrNumber, StringPtr theMessage );
  246. //-----------------------------------------------------------------------
  247.  
  248. void main    (void)
  249. {
  250.     // Init
  251.     DoInit();
  252.     DoMenuSetup();
  253.     OpenStatus();
  254.     
  255.     // Eat events until done
  256.     do
  257.     {
  258.         HandleEvent();
  259.     }
  260.     while (!gQuitFlag);
  261.     
  262.     // Take off, eh?
  263.     ExitToShell();
  264. }
  265.  
  266. //-----------------------------------------------------------------------
  267.  
  268. void    DoInit    (void)
  269. {
  270.     short                    i;
  271.     ComponentDescription    osaDesc;
  272.     
  273.     // Set up quit flag
  274.     gQuitFlag = false;
  275.     
  276.     // MacMantra™
  277.     MaxApplZone();
  278.     InitGraf (&qd.thePort);
  279.     InitFonts();
  280.     FlushEvents (everyEvent, 0);
  281.     InitWindows();
  282.     InitMenus();
  283.     TEInit();
  284.     InitDialogs (0L);
  285.     InitCursor();
  286.     MoreMasters();
  287.     MoreMasters();
  288.     MoreMasters();
  289.     MoreMasters();
  290.     
  291.     // Get initial strings
  292.     GetIndString (gStatusStr, kStatusStrsID, kIdleStr);
  293.     GetIndString (gKeyPhrase, kStatusStrsID, kKeyPhrase);
  294.     
  295.     // Init instance stuff
  296.     gOSAComponentID = 0L;
  297.     gCurrentInstance = 0L;
  298.     for (i = 0; i < kMaxInstances; i++)
  299.         gComponentInstance[i] = 0L;
  300.         
  301.     
  302.     
  303.     
  304.     osaDesc.componentType = 'osa ';
  305.     osaDesc.componentSubType = 'SMPL';
  306.     osaDesc.componentManufacturer = 'appl';
  307.     osaDesc.componentFlags = 0L;
  308.     osaDesc.componentFlagsMask = 0L;
  309.  
  310.     #ifdef DEBUG_IT    
  311.         // Register the osa component
  312.         if (gOSANameHdl == nil)
  313.         {
  314.             Str255    nuosaName = "\pScript Stuff";
  315.             
  316.             gOSANameHdl = NewHandle (sizeof (Str255));
  317.             BlockMove ((Ptr)&nuosaName, (Ptr)(*gOSANameHdl), nuosaName[0] + 1);
  318.         }
  319.         if (gInfoHdl == nil)
  320.         {
  321.             Str255    osaInfo = "\pThis component provides simple scripting services.";
  322.             
  323.             gInfoHdl = NewHandle (sizeof (Str255));
  324.             BlockMove ((Ptr)&osaInfo, (Ptr)(*gInfoHdl), osaInfo[0] + 1);
  325.         }
  326.         gOSAComponentID = RegisterComponent (&osaDesc,
  327.             NewComponentRoutineProc(OSADispatcher), kRegisterLocally,
  328.             gOSANameHdl, gInfoHdl, nil);
  329.         
  330.     #else
  331.  
  332.         gOSAComponentID = FindNextComponent(nil, &osaDesc);
  333.     
  334.     #endif //DEBUG_IT    
  335. }
  336.  
  337. //-----------------------------------------------------------------------
  338.  
  339. void    DoMenuSetup    (void)
  340. {    
  341.     Handle    theMenuBar = GetNewMBar (kMenuBarID);
  342.     
  343.     // Set up our menus
  344.     SetMenuBar (theMenuBar);
  345.     gAppleMenu = GetMHandle (kAppleID);
  346.     gFileMenu = GetMHandle (kFileID);
  347.     
  348.     gEditMenu = GetMHandle (kEditID);
  349.     gTestMenu = GetMHandle (kTestID);
  350.     gInstanceMenu = GetMHandle (kInstanceID);
  351.     gCanDoMenu = GetMenu (kCanDoID);
  352.     InsertMenu (gCanDoMenu, hierMenu);
  353.     AddResMenu (gAppleMenu, 'DRVR');
  354.     DrawMenuBar();
  355. }
  356.  
  357. //-----------------------------------------------------------------------
  358.  
  359. void    HandleEvent    (void)
  360. {
  361.     Boolean    ok = false;
  362.  
  363.     // Do system stuff
  364.     HiliteMenu (0);
  365.     SystemTask();
  366.     
  367.     // Suck an event
  368.     ok = WaitNextEvent (everyEvent, &gTheEvent, 0, 0);
  369.     if (ok)
  370.     {
  371.         // What was it?
  372.         switch (gTheEvent.what)
  373.         {
  374.             case mouseDown:
  375.             {
  376.                 HandleMouseDown();
  377.                 break;
  378.             }
  379.             case keyDown:
  380.             case autoKey:
  381.             {
  382.                 char    theChar = gTheEvent.message & charCodeMask;
  383.                 long    theMenu = MenuKey (theChar);
  384.  
  385.                 HandleMenu (theMenu);                
  386.                 break;
  387.             }
  388.             case updateEvt:
  389.             {
  390.                 if (IsDialogEvent (&gTheEvent))
  391.                 {
  392.                     // Update the status dialog
  393.                     GetPort (&gSavedPort);
  394.                     SetPort (gStatusDialog);
  395.                     BeginUpdate (gStatusDialog);
  396.                     InsetRect (&gStatusBox, -2, -2);
  397.                     FrameRect (&gStatusBox);
  398.                     InsetRect (&gStatusBox, 2, 2);
  399.                     EraseRect (&gStatusBox);
  400.                     SetIText (gStatusText, gStatusStr);
  401.                     EndUpdate (gStatusDialog);
  402.                     SetPort (gSavedPort);
  403.                 }
  404.             }
  405.             default:    // We don't really care about any other events
  406.             {
  407.                 break;
  408.             }
  409.         }
  410.     }
  411. }
  412.  
  413. //-----------------------------------------------------------------------
  414.  
  415. void    HandleMouseDown    (void)
  416. {    
  417.     WindowPtr    theWindow;
  418.     short        windowCode = FindWindow (gTheEvent.where, &theWindow);
  419.     
  420.     // Where was the mouse down?
  421.     switch (windowCode)
  422.     {
  423.         case inSysWindow:
  424.         { 
  425.             SystemClick (&gTheEvent, theWindow);
  426.             break;
  427.         }
  428.         case inMenuBar:
  429.         {
  430.             AdjustMenus();
  431.             HandleMenu (0L);
  432.             break;
  433.         }
  434.         case inDrag:
  435.         {
  436.             DragWindow (theWindow, gTheEvent.where, &(qd.screenBits.bounds));
  437.             break;
  438.         }
  439.         case inGoAway:
  440.         {
  441.             if ((theWindow == gStatusDialog) && 
  442.                 TrackGoAway (gStatusDialog, gTheEvent.where))
  443.             {
  444.                 DisposDialog (gStatusDialog);
  445.                 gStatusDialog = nil;
  446.             }
  447.             break;
  448.         }
  449.         default:
  450.         {
  451.             break;
  452.         }
  453.     }
  454. }
  455.  
  456. //-----------------------------------------------------------------------
  457.  
  458. void    AdjustMenus    (void)
  459. {
  460.     register WindowPeek        wp = nil;
  461.     short                    kind = 0;
  462.     Boolean                    DA = false;
  463.     ComponentDescription    compDesc;
  464.     ComponentResult            result = noErr;
  465.     
  466.     // What kind of window is frontmost?
  467.     wp = (WindowPeek) FrontWindow();
  468.     kind = wp ? wp->windowKind : 0;
  469.     DA = kind < 0;
  470.     
  471.     // Set our menu item states appropriately
  472.     
  473.     // Apple menu
  474.     Enable ((Handle) gAppleMenu, kAboutItem, true);    
  475.     
  476.     // File menu
  477.     Enable ((Handle) gFileMenu, kOpenItem, (gStatusDialog == nil) ? true : false);
  478.     Enable ((Handle) gFileMenu, kCloseItem, DA || ((gStatusDialog != nil) ? true : false));
  479.     
  480.     
  481.     Enable ((Handle) gFileMenu, kOpenComponentItem, true);
  482.     Enable ((Handle) gFileMenu, kCloseComponentItem, (gCurrentInstance != 0L) ? true : false);
  483.     Enable ((Handle) gFileMenu, kQuitItem, true);
  484.  
  485.     // Edit menu
  486.     Enable ((Handle) gEditMenu, 1, DA);
  487.     Enable ((Handle) gEditMenu, 3, DA);
  488.     Enable ((Handle) gEditMenu, 4, DA);
  489.     Enable ((Handle) gEditMenu, 5, DA);
  490.     Enable ((Handle) gEditMenu, 6, DA);
  491.     
  492.     // Test menu
  493.     Enable ((Handle) gTestMenu, kCanDoItem, (gCurrentInstance != 0L) ? true : false);
  494.     Enable ((Handle) gTestMenu, kGetVersionItem, (gCurrentInstance != 0L) ? true : false);
  495.     Enable ((Handle) gTestMenu, kGetNameItem, (gCurrentInstance != 0L) ? true : false);
  496.     Enable ((Handle) gTestMenu, kGetInfoItem, (gCurrentInstance != 0L) ? true : false);
  497.     Enable ((Handle) gTestMenu, kGetRefconItem, (gCurrentInstance != 0L) ? true : false);
  498.     Enable ((Handle) gTestMenu, kGetCountItem, (gCurrentInstance != 0L) ? true : false);
  499.     Enable ((Handle) gTestMenu, kDoIt, (gCurrentInstance != 0L) ? true : false);
  500.  
  501.     // Figure out which item is checked in the Instance menu
  502.     if (CountMItems (gInstanceMenu) > 0)
  503.     {
  504.         short    i;
  505.         short    j;
  506.         long    tempInst;
  507.         Str255    menuItemStr;
  508.         Str255    tempInstStr;
  509.         
  510.         // Enable the menu
  511.         EnableItem (gInstanceMenu, 0);
  512.         
  513.         // Examine each item
  514.         for (i = 1; i <= CountMItems (gInstanceMenu); i++)
  515.         {
  516.             Boolean    foundKey = false;
  517.             
  518.             // Uncheck the item
  519.             CheckItem (gInstanceMenu, i, false);
  520.             
  521.             // Get the item string
  522.             GetItem (gInstanceMenu, i, menuItemStr);
  523.             
  524.             // Extract the instance number from the menu string
  525.             GetItem (gInstanceMenu, i, menuItemStr);
  526.             for (j = 1; j <= menuItemStr[0]; j++)
  527.             {
  528.                 if ((gKeyPhrase[1] == menuItemStr[j]) &&
  529.                     (gKeyPhrase[2] == menuItemStr[j + 1]) &&
  530.                     (gKeyPhrase[3] == menuItemStr[j + 2]) &&
  531.                     (gKeyPhrase[4] == menuItemStr[j + 3]) &&
  532.                     (gKeyPhrase[5] == menuItemStr[j + 4]))
  533.                 {
  534.                     foundKey = true;
  535.                     break;
  536.                 }
  537.             }
  538.             
  539.             // Did we find the phrase key?
  540.             if (foundKey)
  541.             {
  542.                 // Copy the instance string
  543.                 BlockMove ((Ptr)&menuItemStr[j + 5], (Ptr)&tempInstStr[1],
  544.                     menuItemStr[menuItemStr[0] - (j + 4)]);
  545.                 tempInstStr[0] = menuItemStr[0] - (j + 4);
  546.                 
  547.                 // Is it the current instance?
  548.                 HexStrToDecimalNumber ((StringPtr)&tempInstStr, &tempInst);
  549.                 if (tempInst == (long)(gCurrentInstance))
  550.                 {
  551.                     // Check it
  552.                     CheckItem (gInstanceMenu, i, true);
  553.                 }
  554.             }                            
  555.         }
  556.     }
  557.     else    // No instances are currently open, so dim this menu
  558.     {
  559.         DisableItem (gInstanceMenu, 0);
  560.     }
  561.     DrawMenuBar();
  562. }
  563.  
  564. //-----------------------------------------------------------------------
  565.  
  566. void    Enable    (Handle        menu, 
  567.                  short        item, 
  568.                  Boolean    ok)
  569. {
  570.     // Utility routine to enable and disable menu items
  571.     if (ok)
  572.     {
  573.         EnableItem ((MenuHandle) menu, item);
  574.     }
  575.     else
  576.     {
  577.         DisableItem ((MenuHandle) menu, item);
  578.     }
  579. }
  580.  
  581. //-----------------------------------------------------------------------
  582.  
  583. void    HandleMenu    (long    theMenu)
  584. {    
  585.     long                    mSelect;
  586.     short                    menuID;
  587.     short                    menuItem;
  588.     ComponentResult            result = noErr;    
  589.     Str255                    menuItemStr;
  590.     Str255                    tempStr;
  591.     short                    i;
  592.     short                    j;
  593.     ComponentDescription    osaDesc;
  594.     
  595.     // Did we get a menu?
  596.     if (theMenu == 0L)
  597.     {
  598.         // Nope, get it from menu select
  599.         mSelect = MenuSelect (gTheEvent.where);
  600.     }
  601.     else
  602.     {
  603.         // Yep, use it
  604.         mSelect = theMenu;
  605.     }
  606.     
  607.     // Decode it
  608.     menuID = HiWord (mSelect);
  609.     menuItem = LoWord (mSelect);
  610.     
  611.     // Which menu is it?
  612.     switch (menuID)
  613.     {
  614.         case kAppleID:
  615.         {
  616.             if (menuItem == kAboutItem)
  617.             {
  618.                 DoAboutDialog();
  619.             }
  620.             else    // It's a DA
  621.             {
  622.                 Str255    name;
  623.                 
  624.                 // Open the DA
  625.                 GetPort (&gSavedPort);
  626.                 GetItem (gAppleMenu, menuItem, name);
  627.                 OpenDeskAcc (name);
  628.                 SetPort (gSavedPort);
  629.             }
  630.             break;
  631.         }
  632.         case kFileID:
  633.         {
  634.             switch (menuItem)
  635.             {
  636.                 case kOpenItem:
  637.                 {
  638.                     // Open the status dialog
  639.                     OpenStatus();
  640.                     break;
  641.                 }
  642.                 case kCloseItem:
  643.                 {
  644.                     WindowPeek    frontWindow = (WindowPeek) FrontWindow();
  645.                     
  646.                     // Is a window up?
  647.                     if (frontWindow == 0L)
  648.                     {
  649.                         break;
  650.                     }
  651.                     else    // Yep
  652.                     {
  653.                         // What kind of window is it?
  654.                         if (frontWindow->windowKind < 0)
  655.                         {
  656.                             // It's a DA
  657.                             CloseDeskAcc (frontWindow->windowKind);
  658.                         }
  659.                         else
  660.                         {
  661.                             // Is it the status dialog?
  662.                             if (gStatusDialog != nil)
  663.                             {
  664.                                 // Close it
  665.                                 DisposDialog (gStatusDialog);
  666.                                 gStatusDialog = nil;
  667.                             }
  668.                             
  669.                             // Update the menus
  670.                             AdjustMenus();
  671.                         }
  672.                     }
  673.                     break;
  674.                   }
  675.                   
  676.                   
  677.                 case kOpenComponentItem:
  678.                 {
  679.                     OpenOSAComponent ();
  680.                     break;
  681.                 }
  682.                 
  683.                 
  684.                 case kCloseComponentItem:
  685.                 {
  686.                     if (gCurrentInstance != 0L)
  687.                     {
  688.                         // Close the component instance
  689.                         result = CloseComponent (gCurrentInstance);
  690.                         if (result != noErr)
  691.                         {
  692.                             GetIndString (gStatusStr, kStatusStrsID, kErrorClosingInstStr);
  693.                         }
  694.                         else
  695.                         {
  696.                             GetIndString (gStatusStr, kStatusStrsID, kClosedOKStr);
  697.                         }
  698.                         UpdateStatus();
  699.                         
  700.                         // Delete this instance from the instance menu
  701.                         DecimalNumberToHexStr ((long) gCurrentInstance, (StringPtr)&tempStr);
  702.                         for (i = 1; i <= CountMItems (gInstanceMenu); i++)
  703.                         {
  704.                             Str255    tempInstStr;
  705.                             Boolean    foundKey = false;
  706.                             
  707.                             // Extract the instance number from the menu item string
  708.                             GetItem (gInstanceMenu, i, menuItemStr);
  709.                             for (j = 1; j <= menuItemStr[0]; j++)
  710.                             {
  711.                                 if ((gKeyPhrase[1] == menuItemStr[j]) &&
  712.                                     (gKeyPhrase[2] == menuItemStr[j + 1]) &&
  713.                                     (gKeyPhrase[3] == menuItemStr[j + 2]) &&
  714.                                     (gKeyPhrase[4] == menuItemStr[j + 3]) &&
  715.                                     (gKeyPhrase[5] == menuItemStr[j + 4]))
  716.                                 {
  717.                                     foundKey = true;
  718.                                     break;
  719.                                 }
  720.                             }
  721.                             
  722.                             // Did we find the phrase key?
  723.                             if (foundKey)
  724.                             {
  725.                                 // Copy the instance string
  726.                                 BlockMove ((Ptr)&menuItemStr[j + 5], (Ptr)&tempInstStr[1],
  727.                                     menuItemStr[menuItemStr[0] - (j + 4)]);
  728.                                 tempInstStr[0] = menuItemStr[0] - (j + 4);
  729.                                 
  730.                                 // Is this the instance we're closing?
  731.                                 if (RelString (tempInstStr, tempStr, true, true) == 0)
  732.                                 {
  733.                                     // Delete this item from the menu
  734.                                     DelMenuItem (gInstanceMenu, i);
  735.                                     break;
  736.                                 }
  737.                             }                            
  738.                         }
  739.                         
  740.                         // Clear out its slot
  741.                         for (i = 0; i < kMaxInstances; i++)
  742.                         {
  743.                             if (gCurrentInstance == gComponentInstance[i])
  744.                             {
  745.                                 gComponentInstance[i] = 0L;
  746.                                 break;
  747.                             }
  748.                         }
  749.                         gCurrentInstance = 0L;
  750.                         
  751.                         // Set up on another instance in the menu (if there is one)
  752.                         for (i = 0; i < kMaxInstances; i++)
  753.                         {
  754.                             if (gComponentInstance[i] != 0L)
  755.                             {
  756.                                 gCurrentInstance = gComponentInstance[i];
  757.                                 break;
  758.                             }
  759.                         }
  760.                     }
  761.                     
  762.                     // Update the menus
  763.                     AdjustMenus();
  764.                     break;
  765.                 }
  766.                 case kQuitItem:
  767.                 {
  768.                     // We're outta here
  769.                     DoQuit();
  770.                     break;
  771.                 }
  772.                 default:
  773.                 {
  774.                     break;
  775.                 }
  776.             }
  777.             break;
  778.           }    
  779.         case kEditID:
  780.         {
  781.             if (!SystemEdit (menuItem - 1))
  782.             {
  783.                 // We don't really do anything here - feel free to implement something
  784.                 // yourself if you want
  785.                 SysBeep(5);
  786.             }
  787.             break;
  788.         }
  789.         case kTestID:
  790.         {
  791.             Str255    tempStr;
  792.             
  793.             switch (menuItem)
  794.             {
  795.                 case kGetVersionItem:
  796.                 {
  797.                     long    version = GetComponentVersion (gCurrentInstance);
  798.                     
  799.                     tempStr[0] = 0;
  800.                     GetIndString (gStatusStr, kStatusStrsID, kCompVersStr);
  801.                     NumToString ((version >> 16), tempStr);
  802.                     BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  803.                         tempStr[0]);
  804.                     gStatusStr[0] += tempStr[0];
  805.                     GetIndString (tempStr, kStatusStrsID, kInterfaceVersStr);
  806.                     BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  807.                         tempStr[0]);
  808.                     gStatusStr[0] += tempStr[0];
  809.                     NumToString ((version & 0x0000FFFF), tempStr);
  810.                     BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  811.                         tempStr[0]);
  812.                     gStatusStr[0] += tempStr[0] + 1;
  813.                     gStatusStr[gStatusStr[0]] = '.';
  814.                     UpdateStatus();
  815.                     break;
  816.                 }
  817.                 case kGetNameItem:
  818.                 {
  819.                     Handle    nameHdl = NewHandle (sizeof (Str255));
  820.                     
  821.                     if (nameHdl != nil)
  822.                     {
  823.                         result = GetComponentInfo ((Component) gCurrentInstance, 
  824.                             nil, nameHdl, nil, nil);
  825.                         HLock (nameHdl);
  826.                         if ((**nameHdl) == 0)
  827.                         {
  828.                             GetIndString (gStatusStr, kStatusStrsID, kNoNameStr);
  829.                         }
  830.                         else
  831.                         {
  832.                             GetIndString (gStatusStr, kStatusStrsID, kNameStr);
  833.                             BlockMove ((Ptr)&((**((Str255**)(nameHdl)))[1]), 
  834.                                 (Ptr)&gStatusStr[gStatusStr[0] + 1],
  835.                                 (**((Str255**)(nameHdl)))[0]);
  836.                             gStatusStr[0] += (**((Str255**)(nameHdl)))[0] + 2;
  837.                             gStatusStr[gStatusStr[0] - 1] = '”';
  838.                             gStatusStr[gStatusStr[0]] = '.';
  839.                         }
  840.                         HUnlock (nameHdl);
  841.                         DisposHandle (nameHdl);
  842.                     }
  843.                     UpdateStatus();
  844.                     break;
  845.                 }
  846.                 case kGetInfoItem:
  847.                 {
  848.                     Handle    infoHdl = NewHandle (sizeof (Str255));
  849.                     
  850.                     if (infoHdl != nil)
  851.                     {
  852.                         result = GetComponentInfo ((Component) gCurrentInstance, 
  853.                             nil, nil, infoHdl, nil);
  854.                         HLock (infoHdl);
  855.                         if ((**((Str255**)(infoHdl)))[0] == 0)
  856.                         {
  857.                             GetIndString (gStatusStr, kStatusStrsID, kNoInfoStr);
  858.                         }
  859.                         else
  860.                         {
  861.                             GetIndString (gStatusStr, kStatusStrsID, kInfoStr);
  862.                             BlockMove ((Ptr)&((**((Str255**)(infoHdl)))[1]), 
  863.                                 (Ptr)&gStatusStr[gStatusStr[0] + 1],
  864.                                 (**((Str255**)(infoHdl)))[0]);
  865.                             gStatusStr[0] += (**((Str255**)(infoHdl)))[0] + 2;
  866.                             gStatusStr[gStatusStr[0] - 1] = '”';
  867.                             gStatusStr[gStatusStr[0]] = '.';
  868.                         }
  869.                         HUnlock (infoHdl);
  870.                         DisposHandle (infoHdl);
  871.                     }
  872.                     UpdateStatus();
  873.                     break;
  874.                 }
  875.                 case kGetRefconItem:
  876.                 {
  877.                     long    refcon = GetComponentRefcon ((Component)gCurrentInstance);
  878.                     
  879.                     NumToString (refcon, tempStr);
  880.                     GetIndString (gStatusStr, kStatusStrsID, kRefconStr);
  881.                     BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  882.                         tempStr[0]);
  883.                     gStatusStr[0] += tempStr[0] + 1;
  884.                     gStatusStr[gStatusStr[0]] = '.';
  885.                     UpdateStatus();
  886.                     break;
  887.                 }
  888.                 case kGetCountItem:
  889.                 {
  890.                     long    instCount = CountComponentInstances ((Component) gCurrentInstance);
  891.                     
  892.                     NumToString (instCount, tempStr);
  893.                     if (instCount == 1)
  894.                     {
  895.                         GetIndString (gStatusStr, kStatusStrsID, kThereIsStr);
  896.                         BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  897.                             tempStr[0]);
  898.                         gStatusStr[0] += tempStr[0];
  899.                         GetIndString (tempStr, kStatusStrsID, kInstanceStr);
  900.                         BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  901.                             tempStr[0]);
  902.                     }
  903.                     else
  904.                     {
  905.                         GetIndString (gStatusStr, kStatusStrsID, kThereAreStr);
  906.                         BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  907.                             tempStr[0]);
  908.                         gStatusStr[0] += tempStr[0];
  909.                         GetIndString (tempStr, kStatusStrsID, kInstancesStr);
  910.                         BlockMove ((Ptr)&tempStr[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  911.                             tempStr[0]);
  912.                     }
  913.                     gStatusStr[0] += tempStr[0];
  914.                     UpdateStatus();
  915.                     break;
  916.                 }
  917.                 
  918.                 case kDoIt:
  919.                 {
  920.                     short    numerator;
  921.                     short    denominator;
  922.                     short    quotient;
  923.                     Str63    theNumber, theResult;
  924.                     OSErr    anErr;
  925.                     Str255    theErrorMessage;
  926.                     
  927.                     DoOperationDialog (theNumber);
  928.                     anErr = MyDoNewScript(theNumber, theResult);
  929.                     if( anErr == noErr ){
  930.                         gStatusStr[0] = 0;
  931.                         BlockMove ((Ptr)&theNumber[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  932.                             theNumber[0]);
  933.                         gStatusStr[0] += theNumber[0] ;
  934.                         BlockMove ("\p is ",(Ptr)&gStatusStr[ gStatusStr[0] + 1], 4);
  935.                         gStatusStr[0] += 4 ;
  936.                         BlockMove ((Ptr)&theResult[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  937.                             theResult[0]);
  938.                         gStatusStr[0] += theResult[0] + 1;
  939.                         gStatusStr[gStatusStr[0]] = '.';
  940.                     }
  941.                     else{
  942.                         MyGetScriptErrorInfo( &anErr, theErrorMessage );
  943.                         gStatusStr[0] = 0;
  944.                         BlockMove ((Ptr)&theErrorMessage[1], (Ptr)&gStatusStr[gStatusStr[0] + 1],
  945.                             theErrorMessage[0]);
  946.                         gStatusStr[0] += theErrorMessage[0] + 1 ;
  947.                         gStatusStr[gStatusStr[0]] = '.';
  948.                     }
  949.                     UpdateStatus();
  950.                     break;
  951.                 }
  952.                 
  953.                 default:
  954.                 {
  955.                     break;
  956.                 }
  957.             }
  958.             break;
  959.         }
  960.         case kInstanceID:
  961.         {
  962.             Str255    instanceStr;
  963.             Boolean    foundKey = false;
  964.             
  965.             // Get the menu item string
  966.             GetItem (gInstanceMenu, menuItem, menuItemStr);
  967.             
  968.             // Find the key phrase
  969.             for (i = 1; i <= menuItemStr[0]; i++)
  970.             {
  971.                 if ((gKeyPhrase[1] == menuItemStr[i]) &&
  972.                     (gKeyPhrase[2] == menuItemStr[i + 1]) &&
  973.                     (gKeyPhrase[3] == menuItemStr[i + 2]) &&
  974.                     (gKeyPhrase[4] == menuItemStr[i + 3]) &&
  975.                     (gKeyPhrase[5] == menuItemStr[i + 4]))
  976.                 {
  977.                     // Found the key phrase
  978.                     foundKey = true;
  979.                     break;
  980.                 }
  981.             }
  982.             
  983.             // Did we find the key phrase?
  984.             if (foundKey)
  985.             {
  986.                 // Copy the instance string
  987.                 BlockMove ((Ptr)&menuItemStr[i + 5], (Ptr)&instanceStr[1], 
  988.                     menuItemStr[0] - (i + 4));
  989.                 instanceStr[0] = menuItemStr[0] - (i + 4);
  990.                     
  991.                 // Get the instance number from the string
  992.                 HexStrToDecimalNumber ((StringPtr)&instanceStr, (long *)&gCurrentInstance);
  993.                 
  994.                 // Update the menus
  995.                 AdjustMenus();
  996.                 
  997.                 // Get the description for this instance
  998.                 result = GetComponentInfo ((Component) gCurrentInstance, 
  999.                     &osaDesc, nil, nil, nil);
  1000.                 GetIndString (gStatusStr, kStatusStrsID, kCompDescStr);
  1001.                 BlockMove ((Ptr)&(osaDesc.componentType), 
  1002.                     (Ptr)&(gStatusStr[gStatusStr[0] + 1]), 4);
  1003.                 gStatusStr[0] += 4;
  1004.                 gStatusStr[gStatusStr[0] + 1] = ',';
  1005.                 gStatusStr[gStatusStr[0] + 2] = ' ';
  1006.                 gStatusStr[0] += 2;
  1007.                 BlockMove ((Ptr)&(osaDesc.componentSubType), 
  1008.                     (Ptr)&(gStatusStr[gStatusStr[0] + 1]), 4);
  1009.                 gStatusStr[0] += 4;
  1010.                 gStatusStr[gStatusStr[0] + 1] = ',';
  1011.                 gStatusStr[gStatusStr[0] + 2] = ' ';
  1012.                 gStatusStr[0] += 2;
  1013.                 BlockMove ((Ptr)&(osaDesc.componentManufacturer), 
  1014.                     (Ptr)&(gStatusStr[gStatusStr[0] + 1]), 4);
  1015.                 gStatusStr[0] += 4;
  1016.                 gStatusStr[gStatusStr[0] + 1] = ']';
  1017.                 gStatusStr[gStatusStr[0] + 2] = '.';
  1018.                 gStatusStr[0] += 2;
  1019.                 
  1020.                 // Update the status dialog
  1021.                 UpdateStatus();
  1022.             }            
  1023.             break;
  1024.         }
  1025.         case kCanDoID:
  1026.         {
  1027.             switch (menuItem)
  1028.             {
  1029.                 case kCanDoOpenItem:
  1030.                 {
  1031.                     if (ComponentFunctionImplemented (gCurrentInstance,
  1032.                         kComponentOpenSelect))
  1033.                     {
  1034.                         GetIndString (gStatusStr, kStatusStrsID, kCanDoOpenStr);
  1035.                     }
  1036.                     else
  1037.                     {
  1038.                         GetIndString (gStatusStr, kStatusStrsID, kCantDoOpenStr);
  1039.                     }
  1040.                     UpdateStatus();
  1041.                     break;
  1042.                 }
  1043.                 case kCanDoCloseItem:
  1044.                 {
  1045.                     if (ComponentFunctionImplemented (gCurrentInstance,
  1046.                         kComponentCloseSelect))
  1047.                     {
  1048.                         GetIndString (gStatusStr, kStatusStrsID, kCanDoCloseStr);
  1049.                     }
  1050.                     else
  1051.                     {
  1052.                         GetIndString (gStatusStr, kStatusStrsID, kCantDoCloseStr);
  1053.                     }
  1054.                     UpdateStatus();
  1055.                     break;
  1056.                 }
  1057.                 case kCanDoCanDoItem:
  1058.                 {
  1059.                     if (ComponentFunctionImplemented (gCurrentInstance,
  1060.                         kComponentCanDoSelect))
  1061.                     {
  1062.                         GetIndString (gStatusStr, kStatusStrsID, kCanDoCanDoStr);
  1063.                     }
  1064.                     else
  1065.                     {
  1066.                         GetIndString (gStatusStr, kStatusStrsID, kCantDoCanDoStr);
  1067.                     }
  1068.                     UpdateStatus();
  1069.                     break;
  1070.                 }
  1071.                 case kCanDoVersionItem:
  1072.                 {
  1073.                     if (ComponentFunctionImplemented (gCurrentInstance,
  1074.                         kComponentVersionSelect))
  1075.                     {
  1076.                         GetIndString (gStatusStr, kStatusStrsID, kCanDoVersionStr);
  1077.                     }
  1078.                     else
  1079.                     {
  1080.                         GetIndString (gStatusStr, kStatusStrsID, kCantDoVersionStr);
  1081.                     }
  1082.                     UpdateStatus();
  1083.                     break;
  1084.                 }
  1085.                 case kCanDoRegisterItem:
  1086.                 {
  1087.                     if (ComponentFunctionImplemented (gCurrentInstance,
  1088.                         kComponentRegisterSelect))
  1089.                     {
  1090.                         GetIndString (gStatusStr, kStatusStrsID, kCanDoRegisterStr);
  1091.                     }
  1092.                     else
  1093.                     {
  1094.                         GetIndString (gStatusStr, kStatusStrsID, kCantDoRegisterStr);
  1095.                     }
  1096.                     UpdateStatus();
  1097.                     break;
  1098.                 }
  1099.                 case kCanDoTargetItem:
  1100.                 {
  1101.                     if (ComponentFunctionImplemented (gCurrentInstance,
  1102.                         kComponentTargetSelect))
  1103.                     {
  1104.                         GetIndString (gStatusStr, kStatusStrsID, kCanDoTargetStr);
  1105.                     }
  1106.                     else
  1107.                     {
  1108.                         GetIndString (gStatusStr, kStatusStrsID, kCantDoTargetStr);
  1109.                     }
  1110.                     UpdateStatus();
  1111.                     break;
  1112.                 }
  1113.                 default:
  1114.                 {
  1115.                     break;
  1116.                 }
  1117.             }
  1118.             break;
  1119.         }
  1120.         default:
  1121.         {
  1122.             break;
  1123.         }
  1124.     }
  1125. }
  1126.  
  1127. //-----------------------------------------------------------------------
  1128.  
  1129. void    OpenStatus    (void)
  1130. {
  1131.     // Get the dialog
  1132.     gStatusDialog = GetNewDialog (kStatusDialogID, nil, (WindowPtr)-1L);
  1133.     
  1134.     // Did we get it?
  1135.     if (gStatusDialog != nil)
  1136.     {
  1137.         short    itemType;
  1138.         
  1139.         GetPort (&gSavedPort);
  1140.         SetPort (gStatusDialog);
  1141.         TextFont (geneva);
  1142.         TextFace (0);
  1143.         TextSize (10);
  1144.         GetDItem (gStatusDialog, kStatusBox, &itemType, &gStatusText, &gStatusBox);
  1145.         InsetRect (&gStatusBox, -2, -2);
  1146.         FrameRect (&gStatusBox);
  1147.         InsetRect (&gStatusBox, 2, 2);
  1148.         EraseRect (&gStatusBox);
  1149.         SetIText (gStatusText, gStatusStr);
  1150.     }
  1151.     
  1152.     // Update the menus
  1153.     AdjustMenus();
  1154. }
  1155.  
  1156. //-----------------------------------------------------------------------
  1157.  
  1158. void    UpdateStatus    (void)
  1159. {
  1160.     // If we've got a status dialog, update it
  1161.     if (gStatusDialog != nil)
  1162.     {
  1163.         GetPort (&gSavedPort);
  1164.         SetPort (gStatusDialog);
  1165.         InvalRect (&gStatusBox);
  1166.         SetPort (gSavedPort);
  1167.     }
  1168. }
  1169.  
  1170. //-----------------------------------------------------------------------
  1171.  
  1172. void    OpenOSAComponent()
  1173. {
  1174.     short        i;
  1175.     Str255        tempStr;
  1176.     Component    osaComponentID;
  1177.     short        osaTypeStrID;
  1178.     Boolean        foundSlot = false;
  1179.     
  1180.     
  1181.     osaComponentID = gOSAComponentID; 
  1182.     osaTypeStrID = kOSAStr;
  1183.  
  1184.  
  1185.     for (i = 0; i < kMaxInstances; i++)
  1186.     {
  1187.         // Is this slot open?
  1188.         if (gComponentInstance[i] == 0L)
  1189.         {
  1190.             // Open the component
  1191.             gComponentInstance[i] = 
  1192.                      OpenComponent (osaComponentID);
  1193.             //    ASInit(gComponentInstance[i], kOSAModeNull,  4*1024, 16*1024, 32 * 1024,
  1194.             //        32*1024, 128* 1024, 64 * 1024 * 1024);
  1195.                 gCurrentInstance = gComponentInstance[i];
  1196.                 foundSlot = true;
  1197.                 break;
  1198.         }
  1199.     }
  1200.     
  1201.     
  1202.     // There were no open slots (we've opened as many instances as our test
  1203.     // program will allow)
  1204.     if (!foundSlot)
  1205.     {
  1206.         GetIndString (gStatusStr, kStatusStrsID, kCantOpenAnyMoreInstStr);
  1207.     }
  1208.     else if (gCurrentInstance != 0L)    // We successfully opened the component
  1209.     {
  1210.         Str255    osaTypeStr;
  1211.         
  1212.         GetIndString (osaTypeStr, kStatusStrsID, osaTypeStrID);
  1213.         GetIndString (gStatusStr, kStatusStrsID, kFoundCompIDAndInstStr);
  1214.         DecimalNumberToHexStr ((long) gCurrentInstance, (StringPtr)&tempStr);
  1215.         BlockMove ((Ptr)&tempStr[1], (Ptr)&osaTypeStr[osaTypeStr[0] + 1],
  1216.             tempStr[0]);
  1217.         osaTypeStr[0] += tempStr[0];
  1218.         InsMenuItem (gInstanceMenu, osaTypeStr, 255);
  1219.     }
  1220.     else    // We couldn't open an instance of the component
  1221.     {
  1222.         GetIndString (gStatusStr, kStatusStrsID, kDidNotGetInstStr);
  1223.     }
  1224.     
  1225.     // Update everything
  1226.     UpdateStatus();
  1227.     AdjustMenus();
  1228. }
  1229.  
  1230. //-----------------------------------------------------------------------
  1231.  
  1232. void    DoAboutDialog    (void)
  1233. {
  1234.     short        itemHit;
  1235.     short        itemType;
  1236.     Handle        itemHandle;
  1237.     Rect        itemRect;
  1238.     DialogPtr    aboutDialog = GetNewDialog (kAboutDialogID, nil, (WindowPtr)-1L);
  1239.     UserItemUPP DrawOKOutlineUPP = NewUserItemProc(DrawOKOutline);    
  1240.  
  1241.     // Do the boring about dialog
  1242.     GetDItem (aboutDialog, kOKButtonOutline, &itemType, &itemHandle, &itemRect);
  1243.     SetDItem (aboutDialog, kOKButtonOutline, itemType, 
  1244.         (Handle) DrawOKOutlineUPP, &itemRect);
  1245.     do
  1246.     {
  1247.         ModalDialog (nil, &itemHit);
  1248.     }
  1249.     while (itemHit != kOKButton);
  1250.     DisposDialog (aboutDialog);
  1251. }
  1252.  
  1253. //-----------------------------------------------------------------------
  1254.  
  1255. void    DoOperationDialog    (Str63 theNumber)
  1256. {
  1257.     DialogPtr    opDialog = GetNewDialog (kOpDialogID, nil, (WindowPtr)-1L);
  1258.     
  1259.     // Did we get a dialog?
  1260.     if (opDialog != nil)
  1261.     {
  1262.         short    itemHit;
  1263.         short    itemType;
  1264.         Handle    itemHandle;
  1265.         Rect    itemRect;
  1266.         Str255    tempStr;
  1267.         long    tempNum;
  1268.         short    *firstNum;
  1269.         short    *secondNum;
  1270.         
  1271.         GetDItem (opDialog, kFirstNumBox, &itemType, &itemHandle, &itemRect);
  1272.         //NumToString (23L, tempStr);
  1273.         //SetIText (itemHandle, tempStr);
  1274.         
  1275.         //GetDItem (opDialog, kSecondNumBox, &itemType, &itemHandle, &itemRect);
  1276.         //NumToString (4L, tempStr);
  1277.         //SetIText (itemHandle, tempStr);
  1278.         
  1279.         // Go get two numbers from the user
  1280.         do
  1281.         {
  1282.             ModalDialog (nil, &itemHit);
  1283.         }
  1284.         while (itemHit != kOKButton);
  1285.         
  1286.         // Give the two numbers back to the caller
  1287.         GetDItem (opDialog, kFirstNumBox, &itemType, &itemHandle, &itemRect);
  1288.         GetIText (itemHandle, theNumber);
  1289.         //StringToNum (tempStr, &tempNum);
  1290.         //*firstNum = (short) tempNum;
  1291.         
  1292.         //GetDItem (opDialog, kSecondNumBox, &itemType, &itemHandle, &itemRect);
  1293.         //GetIText (itemHandle, tempStr);
  1294.         //StringToNum (tempStr, &tempNum);
  1295.         //*secondNum = (short) tempNum;
  1296.         
  1297.         // Clean up
  1298.         DisposDialog (opDialog);
  1299.     }
  1300. }
  1301.  
  1302. //-----------------------------------------------------------------------
  1303.  
  1304. static    pascal    void    DrawOKOutline    (DialogPtr    theDialog,
  1305.                                          short        theItem)
  1306. {
  1307.     short    itemType;
  1308.     Handle    itemHandle;
  1309.     Rect    itemRect;
  1310.     
  1311.     // Draws the OK button outline
  1312.     SetPort (theDialog);
  1313.     GetDItem (theDialog, kOKButtonOutline, &itemType, &itemHandle, &itemRect);
  1314.     PenSize (3, 3); 
  1315.     InsetRect (&itemRect, -4, -4);
  1316.     FrameRoundRect (&itemRect, 16, 16);
  1317.     PenSize (1, 1);
  1318. }
  1319.  
  1320. //-----------------------------------------------------------------------
  1321.  
  1322. void    DoQuit    (void)
  1323. {
  1324.     ComponentResult    result = noErr;
  1325.     short            i;
  1326.     
  1327.     // Walk our instance array and close all instances
  1328.     for (i = 0; i < kMaxInstances; i++)
  1329.     {
  1330.         if (gComponentInstance[i] != 0L)
  1331.         {
  1332.             result = CloseComponent (gComponentInstance[i]);
  1333.             gComponentInstance[i] = 0L;
  1334.         }
  1335.     }
  1336.     // Note that it's not necessary to unregister the components
  1337.     // or dispose of the string handles for the name and info
  1338.     // strings when we're in debug mode - this is because we registered 
  1339.     // the components locally, and as soon as the application heap 
  1340.     // shuts down (that is, the app quits), the Component Manager 
  1341.     // automatically unregisters any components local to that app heap and 
  1342.     // disposes of the component handles properly.
  1343.     
  1344.     // Set quit flag
  1345.     gQuitFlag = true;
  1346. }
  1347.  
  1348. //-----------------------------------------------------------------------
  1349.  
  1350. void    DecimalNumberToHexStr    (long        theDecimalNumber,
  1351.                                  StringPtr    theHexStr)
  1352. {
  1353.     // Utility routine to convert a decimal number into a
  1354.     // hex number string    
  1355.     
  1356.     long    testNybble;
  1357.     char    hexStr[8];
  1358.     Str255    tempStr;
  1359.     short    i;
  1360.     
  1361.     for (i = 7; i >= 0; i--)
  1362.     {
  1363.         testNybble = (theDecimalNumber & (0xF0000000 >> (4 * i))) >> ((7 - i) * 4);
  1364.         
  1365.         if ((testNybble == 8) || (testNybble == 9))    // is it 8 or 9?
  1366.         {
  1367.             NumToString (testNybble, tempStr);
  1368.             hexStr[i] = tempStr[1];
  1369.         }
  1370. //MA changed
  1371. //        else if ((testNybble & 0x00000008) == 1)    // is it between A and F?
  1372.         else if ((testNybble & 0x00000008))    // is it between A and F?
  1373.         {
  1374.             if (testNybble == 10)
  1375.                 hexStr[i] = 'A';
  1376.             else if (testNybble == 11)
  1377.                 hexStr[i] = 'B';
  1378.             else if (testNybble == 12)
  1379.                 hexStr[i] = 'C';
  1380.             else if (testNybble == 13)
  1381.                 hexStr[i] = 'D';
  1382.             else if (testNybble == 14)
  1383.                 hexStr[i] = 'E';
  1384.             else if (testNybble == 15)
  1385.                 hexStr[i] = 'F';
  1386.         }
  1387.         else                                        // it's between 0 and 7
  1388.         {
  1389.             NumToString (testNybble, tempStr);
  1390.             hexStr[i] = tempStr[1];
  1391.         }
  1392.     }
  1393.     BlockMove ((Ptr)&hexStr, (Ptr)&theHexStr[1], 8);
  1394.     theHexStr[0] = 8;
  1395. }
  1396.  
  1397. //-----------------------------------------------------------------------
  1398.  
  1399. OSErr    HexStrToDecimalNumber    (StringPtr    theHexStr,
  1400.                                  long        *theDecimalNumber)
  1401. {
  1402.     // Utility routine to convert a hex number string into
  1403.     // a decimal number
  1404.     
  1405.     OSErr    result = noErr;
  1406.     long    decimalNum = 0L;
  1407.     short    i;
  1408.     long    hexDigitValue;
  1409.     Str255    tempStr;
  1410.     
  1411.     tempStr[0] = 1;
  1412.     if (theHexStr[0] > 8)
  1413.     {
  1414.         result = kGenericError;
  1415.     }
  1416.     else
  1417.     {
  1418.         for (i = 1; i <= 8; i++)
  1419.         {
  1420.             if (theHexStr[i] >= 0x30 && theHexStr[i] <= 0x39)    // it's between 0 and 9
  1421.             {
  1422.                 tempStr[1] = theHexStr[i];
  1423.                 StringToNum (tempStr, &hexDigitValue);
  1424.                 decimalNum += hexDigitValue << (4 * (8 - i));
  1425.             }
  1426.             else if ((theHexStr[i] >= 0x41 && theHexStr[i] <= 0x46) ||
  1427.                 (theHexStr[i] >= 0x61 && theHexStr[i] <= 0x66))    // it's between A and F
  1428.             {
  1429.                 switch (theHexStr[i])
  1430.                 {
  1431.                     case 'A':
  1432.                     case 'a':
  1433.                         hexDigitValue = 10;
  1434.                         break;
  1435.                     case 'B':
  1436.                     case 'b':
  1437.                         hexDigitValue = 11;
  1438.                         break;
  1439.                     case 'C':
  1440.                     case 'c':
  1441.                         hexDigitValue = 12;
  1442.                         break;
  1443.                     case 'D':
  1444.                     case 'd':
  1445.                         hexDigitValue = 13;
  1446.                         break;
  1447.                     case 'E':
  1448.                     case 'e':
  1449.                         hexDigitValue = 14;
  1450.                         break;
  1451.                     case 'F':
  1452.                     case 'f':
  1453.                         hexDigitValue = 15;
  1454.                         break;
  1455.                 }
  1456.                 decimalNum += hexDigitValue << (4 * (8 - i));
  1457.             }
  1458.             else
  1459.             {
  1460.                 result = kGenericError;
  1461.             }
  1462.         }
  1463.     }
  1464.     
  1465.     *theDecimalNumber = decimalNum;    
  1466.     return (result);
  1467. }
  1468.                              
  1469. //-----------------------------------------------------------------------
  1470. OSErr MyDoNewScript(Str63 theNumber, Str63 theResult)
  1471. {
  1472.     AEDesc    scriptText, resultText, componentName;
  1473.     OSAID    scriptID, resultID, contextID = 0;
  1474.     OSAError    myOSAErr, ignoreErr;
  1475.     long        myLong;
  1476.     
  1477.     myOSAErr = OSAScriptingComponentName(gCurrentInstance, &componentName);
  1478.     AECreateDesc(typeChar, &theNumber[1], theNumber[0], &scriptText);
  1479.     scriptID = kOSANullScript;
  1480.     myOSAErr = OSACompile(gCurrentInstance, &scriptText, kOSAModeNull, &scriptID);
  1481.     ignoreErr = AEDisposeDesc(&scriptText);
  1482.     if(myOSAErr == noErr){
  1483.         myOSAErr = OSAExecute(gCurrentInstance, scriptID, contextID, kOSAModeNull, &resultID);
  1484.         ignoreErr = OSADispose(gCurrentInstance, scriptID);
  1485.         if(myOSAErr == noErr){
  1486.             myOSAErr = OSADisplay(gCurrentInstance, resultID, typeChar, kOSAModeNull,
  1487.                                     &resultText);
  1488.             HLock( resultText.dataHandle );
  1489.             myLong = GetHandleSize( resultText.dataHandle );
  1490.             BlockMove( *(resultText.dataHandle), &theResult[1], myLong);
  1491.             theResult[0] = myLong;
  1492.             HUnlock( resultText.dataHandle );
  1493.             ignoreErr = OSADispose(gCurrentInstance, resultID);
  1494.         }
  1495.     }
  1496.     return myOSAErr;
  1497. //-----------------------------------------------------------------------
  1498. void MyGetScriptErrorInfo(short *theErrNumber, StringPtr theMessage )
  1499. {
  1500.  
  1501.     Handle    errorMessage;
  1502.     AEDesc    myDesc, recordDesc;
  1503.     DescType    actualType;
  1504.     Size        actualSize;
  1505.     OSErr        scriptErr, myErr, ignoreErr;
  1506.     OSAError    myOSAErr;
  1507.     long        myLong;
  1508.     
  1509.     myOSAErr = OSAScriptError( gCurrentInstance, kOSAErrorNumber, typeShortInteger, &myDesc);
  1510.     *theErrNumber = **(myDesc.dataHandle);
  1511.     
  1512.     ignoreErr = AEDisposeDesc(&myDesc);
  1513.     
  1514.     myOSAErr = OSAScriptError( gCurrentInstance, kOSAErrorMessage, typeChar, &myDesc);
  1515.     myLong = GetHandleSize(myDesc.dataHandle);
  1516.     HLock(myDesc.dataHandle);
  1517.     BlockMove( *(myDesc.dataHandle), &theMessage[1], myLong) ;
  1518.     theMessage[0] = myLong;
  1519.     HUnlock(myDesc.dataHandle);
  1520.     
  1521.     ignoreErr = AEDisposeDesc(&myDesc);
  1522. }
  1523.